﻿/*
 * ©2009-2010 XELF
 * http://xelf.info
 */

#if XNA || SILVERLIGHT || WINDOWS_PHONE
using Microsoft.Xna.Framework;
using _Quaternion = Microsoft.Xna.Framework.Quaternion;
using _QuaternionHelper = XELF.Framework.QuaternionHelper;
#else
using _Quaternion = XELF.Framework.Quaternion;
using _QuaternionHelper = XELF.Framework.Quaternion;
#endif

namespace XELF.Framework {
#if XNA || SILVERLIGHT || WINDOWS_PHONE
	public static partial class QuaternionHelper {
		/// <summary>
		/// 参照するクォータニオンとのなす角度がπ/2以上の場合、
		/// 符号を反転した値を返す。そうでなければ、そのままの値を返す。
		/// </summary>
		/// <param name="this"></param>
		/// <param name="reference"></param>
		/// <param name="result"></param>
		public static void Regularize(this Quaternion @this, ref Quaternion reference, out Quaternion result) {
			float cosine;
			_Quaternion.Dot(ref @this, ref reference, out cosine);
			if (cosine < 0.0f) {
				_Quaternion.Negate(ref @this, out result);
			} else {
				result = @this;
			}
		}
#else
	public partial struct Quaternion {
		/// <summary>
		/// 参照するクォータニオンとのなす角度がπ/2以上の場合、
		/// 符号を反転した値を返す。そうでなければ、そのままの値を返す。
		/// </summary>
		/// <param name="reference"></param>
		/// <param name="result"></param>
		public void Regularize(ref Quaternion reference, out Quaternion result) {
			float cosine;
			Dot(ref this, ref reference, out cosine);
			if (cosine < 0.0f) {
				Negate(ref this, out result);
			} else {
				result = this;
			}
		}
#endif

		public static bool AreEqual(ref Quaternion a, ref Quaternion b, float delta) {
			return
				MathHelper.AreEqual(a.X, b.X, delta) &&
				MathHelper.AreEqual(a.Y, b.Y, delta) &&
				MathHelper.AreEqual(a.Z, b.Z, delta) &&
				MathHelper.AreEqual(a.W, b.W, delta);
		}
	}
}
